package com.stox.ui.javafx.charting.event.listener;

import java.util.Calendar;
import java.util.List;

import javafx.geometry.Bounds;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.stereotype.Component;

import com.stox.client.BarClient;
import com.stox.event.AbstractModelSelectionEvent;
import com.stox.model.AbstractModel;
import com.stox.model.Bar;
import com.stox.ui.javafx.charting.model.enumeration.Span;
import com.stox.ui.javafx.charting.model.plot.BarPrimaryPlot;
import com.stox.ui.javafx.charting.view.ChartingView;
import com.stox.ui.javafx.charting.widget.ChartTypeComboBox;
import com.stox.ui.javafx.charting.widget.SpanComboBox;
import com.stox.ui.javafx.core.launcher.StoxUiJavaFXApplication;
import com.stox.ui.javafx.core.widget.StoxStage;
import com.stox.ui.javafx.navigator.view.NavigatorView;
import com.stox.util.ApplicationContextUtil;

@Component
public class ModelSelectionEventListener implements SmartApplicationListener {

	@Autowired
	private BarClient barClient;
	
	@Autowired
	private SpanComboBox spanComboBox;
	
	@Autowired
	private ChartTypeComboBox chartTypeComboBox;
	
	@Override
	@SuppressWarnings("unchecked")
	public void onApplicationEvent(ApplicationEvent event) {
		List<AbstractModel> models = (List<AbstractModel>)event.getSource();
		
		int count = models.size();
		int rows = 1;
		int columns = 1;
		
		while((rows*columns) < count){
			rows++;
			if((rows*columns) < count){
				columns++;
			}
		}
		
		ChartingView selectedChartingView = ChartingView.getSelectedChartingView();
		if(null == selectedChartingView) {
			selectedChartingView = new ChartingView();
			selectedChartingView.open();
		}
		
		if(!selectedChartingView.isSelected()) {
			setSize(selectedChartingView, 1, 1, 1, 1);
			setPosition(selectedChartingView, 1, 1, 1, 1);
			selectedChartingView.toFront();
			selectedChartingView.requestFocus();
			
		}
		
		//if replace on selected chart
		AbstractModel abstractModel = models.get(0);
		BarPrimaryPlot plot = new BarPrimaryPlot(abstractModel);
		plot.setChartType(chartTypeComboBox.getValue());
		plot.setData(getData(abstractModel));
		selectedChartingView.getPrimaryChart().setFrontPlot(plot);
		
		for(int i = 1; i < models.size(); i++ ) {
			abstractModel = models.get(i);
			plot = new BarPrimaryPlot(abstractModel);
			plot.setChartType(chartTypeComboBox.getValue());
			plot.setData(getData(abstractModel));
			selectedChartingView.getPrimaryChart().addPlot(plot);
		}
		
		//if overlap on selected chart
	/*	for(int i = 1; i <= models.size(); i++ ) {
			BarPrimaryPlot plot = new BarPrimaryPlot(models.get(i-1));
			selectedChartingView.getPrimaryChart().addPrimaryPlot(plot);
			plot.setData(barClient.findByScripCode(models.get(i-1).getCode()));
		}*/
		
		if(!selectedChartingView.isVisible()) selectedChartingView.setVisible(true);
		selectedChartingView.update();
			
		
		//if show on new charts
		/*for(int i = 1; i <= models.size(); i++ ) {
			ChartingView view = new ChartingView();
			setSize(view, count, i, rows, columns);
			setPosition(view, count, i, rows, columns);
			StoxStage.getRoot().getChildren().add(view);
			view.open();
			
			BarPrimaryPlot plot = new BarPrimaryPlot(models.get(i-1));
			view.getPrimaryChart().setFrontPrimaryPlot(plot);
			plot.setData(barClient.findByScripCode(models.get(i-1).getCode()));
			view.update();
		}*/
	}
	
	private List<Bar> getData(AbstractModel abstractModel){
		Calendar calendar = Calendar.getInstance();
		Span span = spanComboBox.getValue();
		calendar.add(span.getUnit(), -1*span.getCount());
		return barClient.findByScripCode(abstractModel.getCode(), calendar.getTime());
	}
	
	private void setSize(ChartingView view, int count, int index, int rows, int columns) {
		double width = StoxStage.getContentPane().getWidth();
		double height = StoxStage.getContentPane().getHeight();
		
		NavigatorView navigatorView = ApplicationContextUtil.getApplicationContext().getBean(NavigatorView.class);
		double x = navigatorView.getLayoutBounds().getMaxX();
		if(x < width/2) {
			width -= x;
		}
		
		height = height/rows;
		width = width/columns;
		if(index == count){
			width += ((rows*columns)-index)*width;
		}
		view.setPrefWidth(width);
		view.setPrefHeight(height);
	}
	
	private void setPosition(ChartingView view, int count, int index, int rows, int columns) {
		NavigatorView navigatorView = ApplicationContextUtil.getApplicationContext().getBean(NavigatorView.class);
		Bounds bounds = navigatorView.localToScene(navigatorView.getBoundsInLocal());
		
		double x = bounds.getMaxX();
		double y = StoxStage.getContentPane().getLayoutY();
		double width = StoxStage.getContentPane().getWidth() - x;
		double height = StoxStage.getContentPane().getHeight();

		height = height/rows;
		width = width/columns;
		
		int row = 1;
		int column = 1;
		int counter = 1;
		boolean shouldBreak = false;
		for(int i = 1; i <= rows; i++){
			for(int j = 1; j <= columns; j++){
				if(counter == index){
					row = i;
					column = j;
					shouldBreak = true;
					break;
				}
				counter++;
			}
			if(shouldBreak){
				break;
			}
		}
		
		 final double scaleX = view.localToSceneTransformProperty().getValue().getMxx();
         final double scaleY = view.localToSceneTransformProperty().getValue().getMyy();
		
		view.setLayoutX((x+(column-1)*width)/scaleX);
		view.setLayoutY((y+(row-1)*height)/scaleY);
	}
	
	
	public static void main(String args[]) {
		StoxUiJavaFXApplication.main(args);
	}

	@Override
	public int getOrder() {
		return 0;
	}

	@Override
	public boolean supportsEventType(Class<? extends ApplicationEvent> clazz) {
		return AbstractModelSelectionEvent.class.isAssignableFrom(clazz);
	}

	@Override
	public boolean supportsSourceType(Class<?> clazz) {
		return AbstractModel.class.isAssignableFrom(clazz);
	}
	
}
